#!/bin/sh

echo "Now we are building TERN replayer, please make sure your llvm is 2.6 released version, and your \$DEFENS_ROOT setting is correct."
echo "Please make sure you current directory is $DEFENS_ROOT/rcs-modules/klee/."
echo "Please make sure you have installed TERN successfully using tern-install.sh."
echo "Please make sure you have specified the three arguments like this: sh tern-build-replayer.sh BC_PATH BC_NAME REPLAY_PATH"
echo "	BC_PATH: absolute path of your original llvm bc file."
echo "	BC_NAME: name of your original llvm bc file (without .bc, for example, if the bc file is httpd.bc, then you only need to specify \"httpd\"). The suffix must be .bc."
echo "	REPLAY_PATH: absolute path of the replaying X86 programs. It may be different from BC_PATH for some applications like httpd."
echo "Example:"
echo "sh tern-build-replayer.sh /home/heming/bugs/apache-25520/httpd-2.0.46/.libs/    httpd    /home/heming/bugs/apache-25520/apache2/bin/"

BC_PATH=$1
BC_NAME=$2
REPLAY_PATH=$3
FAST=$4;

if [ "$BC_PATH"X = "X" ]; 
then
	echo "Please specify BC_PATH."
	exit 1
fi

if [ "$BC_NAME"X = "X" ]; 
then
	echo "Please specify BC_NAME."
	exit 1
fi

if [ "$REPLAY_PATH"X = "X" ]; 
then
	echo "Please specify REPLAY_PATH."
	exit 1
fi

echo "BC_PATH is: $BC_PATH"
echo "BC_NAME is: $BC_NAME"
echo "REPLAY_PATH is: $REPLAY_PATH"
ORIG_BC=$BC_PATH/$BC_NAME".bc"
REPLAY_BC=$REPLAY_PATH/$BC_NAME"-replay.bc"
REPLAY_ASM=$REPLAY_PATH/$BC_NAME"-replay.s"
REPLAY_EXE=$REPLAY_PATH/$BC_NAME"-tern"

rm -rf REPLAY_BC
rm -rf REPLAY_ASM
rm -rf REPLAY_EXE

# cd llvm-instrument/trace-sync-events
opt -load $DEFENS_ROOT/llvm-obj/Debug/lib/trace-sync-events-stub.so --trace_sync_events_stub  $ORIG_BC > $REPLAY_BC
# cd ../../

# Heming: for my own debug purpose. Will delete this in the future.
make ENABLE_OPTIMIZED=0

# build exe file.
if [ "$FAST"X = "X" ]; 
then
	echo "Converting bc file to asm file..."
	llc -f -o $REPLAY_ASM $REPLAY_BC
else
	echo "Do not covert bc file to asm file because the 4 th argument is $FAST..."
fi

echo "Building instrumented executable file..."
g++ -I$DEFENS_ROOT/llvm-2.6/include -I$DEFENS_ROOT/llvm-obj/include -I$DEFENS_ROOT/rcs-modules/klee/include \
-I$DEFENS_ROOT/rcs-modules/klee/tools/klee -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -fno-exceptions \
-fPIC -Woverloaded-virtual -DLLVM_23 -I$DEFENS_ROOT/rcs-modules/klee/stp/include -DKLEE_DIR="$DEFENS_ROOT/rcs-modules/klee" -g -O2 \
-pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -Wl,-R -Wl,$DEFENS_ROOT/rcs-modules/klee/Debug/bin \
-Wl,-export-dynamic -L$DEFENS_ROOT/rcs-modules/klee/Debug/lib -L$DEFENS_ROOT/llvm-obj/Debug/lib -L$DEFENS_ROOT/rcs-modules/klee/stp/lib \
-o $REPLAY_EXE $REPLAY_ASM -lkleeReplayer  -lkleeSchedCache -lkleeTernOptions \
-lkleaverSolver -lkleaverExpr -lkleeSupport -lkleeBasic -lLLVMSupport -lLLVMSystem -lm -lpthread -ldl -lrt -lcrypt -lbz2  -lz -lcrypt -lnsl \
-lstp_c_interface -lstp_AST -lstp_bitvec -lstp_constantbv -lstp_sat -lstp_simplifier

# The command below is just for future reference.
#g++ -I$DEFENS_ROOT/llvm-2.6/include -I$DEFENS_ROOT/llvm-obj/include -I$DEFENS_ROOT/rcs-modules/klee/include \
#-I$DEFENS_ROOT/rcs-modules/klee/tools/klee -D_DEBUG -D_GNU_SOURCE -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -fno-exceptions \
#-fPIC -Woverloaded-virtual -DLLVM_23 -I$DEFENS_ROOT/rcs-modules/klee/stp/include -DKLEE_DIR="$DEFENS_ROOT/rcs-modules/klee" -O2 \
#-pedantic -Wno-long-long -Wall -W -Wno-unused-parameter -Wwrite-strings -Wl,-R -Wl,$DEFENS_ROOT/rcs-modules/klee/Debug/bin \
#-Wl,-export-dynamic -L$DEFENS_ROOT/rcs-modules/klee/Debug/lib -L$DEFENS_ROOT/llvm-obj/Debug/lib -L$DEFENS_ROOT/rcs-modules/klee/stp/lib \
#-o $REPLAY_EXE $REPLAY_ASM -lkleeReplayer  -lkleeSchedCache -lkleeMemoizer -lkleeTernOptions -lkleeModule \
#-lkleaverSolver -lkleaverExpr -lkleeSupport -lkleeBasic -lLLVMX86AsmParser -lLLVMX86AsmPrinter \
#-lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMX86Info -lLLVMLinker -lLLVMArchive -lLLVMipo -lLLVMBitWriter -lLLVMBitReader -lLLVMJIT \
#-lLLVMExecutionEngine -lLLVMCodeGen -lLLVMScalarOpts -lLLVMTransformUtils -lLLVMipa \
#-lLLVMAnalysis -lLLVMTarget -lLLVMMC -lLLVMCore -lLLVMSupport -lLLVMSystem -ldl -lm -lstp -Bstatic -lpthread  -lpthread -lcrypt -ldl -lrt
#-lidm

echo "\n\nThe replayer exe file for TERN is located at $REPLAY_EXE. You can use it as below:"
echo "$REPLAY_EXE <other arguments you application will need>."
echo "Before you run the replayer program, please make sure you have put correct schedule and constraint files to the correct directory (specified in the option config file)."

# Special hack for pbzip2, just use pbzip2-replay.bc to cover pbzip2-no-usleep-replay.bc, since "no-usleep" version is only for replaying part.
if [ "$BC_NAME" = "pbzip2-no-usleep" ]; 
then
	echo "Copying $BC_NAME..."
	cp $REPLAY_PATH/"pbzip2-replay.bc" $REPLAY_BC
fi

